package cn.ctyun.videoplayer.widget;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;

import org.fourthline.cling.model.meta.Device;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;

import cn.ctyun.videoplayer.R;
import cn.ctyun.videoplayer.adapter.DLNADevicesAdapter;
import cn.ctyun.videoplayer.bean.DanmakuDetail;
import cn.ctyun.videoplayer.bean.DanmakuModel;
import cn.ctyun.videoplayer.controller.DLNAControllerInterface;
import cn.ctyun.videoplayer.controller.DanmakuControllerInterfaceBase;
import cn.ctyun.videoplayer.controller.StandardVideoController;
import cn.ctyun.videoplayer.danmaku.BiliDanmukuParser;
import cn.ctyun.videoplayer.dlnaupnp.Intents;
import cn.ctyun.videoplayer.dlnaupnp.control.ClingPlayControl;
import cn.ctyun.videoplayer.dlnaupnp.control.callback.ControlCallback;
import cn.ctyun.videoplayer.dlnaupnp.entity.ClingDevice;
import cn.ctyun.videoplayer.dlnaupnp.entity.ClingDeviceList;
import cn.ctyun.videoplayer.dlnaupnp.entity.DLANPlayState;
import cn.ctyun.videoplayer.dlnaupnp.entity.IDevice;
import cn.ctyun.videoplayer.dlnaupnp.entity.IResponse;
import cn.ctyun.videoplayer.dlnaupnp.listener.BrowseRegistryListener;
import cn.ctyun.videoplayer.dlnaupnp.listener.DeviceListChangedListener;
import cn.ctyun.videoplayer.dlnaupnp.service.ClingUpnpService;
import cn.ctyun.videoplayer.dlnaupnp.service.manager.ClingManager;
import cn.ctyun.videoplayer.dlnaupnp.service.manager.DeviceManager;
import cn.ctyun.videoplayer.dlnaupnp.util.Utils;
import cn.ctyun.videoplayer.player.IjkVideoView;
import cn.ctyun.videoplayer.util.PlayerConstants;
import cn.ctyun.videoplayer.controller.DanmakuController;
import master.flame.danmaku.controller.IDanmakuView;
import master.flame.danmaku.danmaku.loader.ILoader;
import master.flame.danmaku.danmaku.loader.IllegalDataException;
import master.flame.danmaku.danmaku.loader.android.DanmakuLoaderFactory;
import master.flame.danmaku.danmaku.model.BaseDanmaku;
import master.flame.danmaku.danmaku.model.DanmakuTimer;
import master.flame.danmaku.danmaku.model.IDanmakus;
import master.flame.danmaku.danmaku.model.IDisplayer;
import master.flame.danmaku.danmaku.model.android.DanmakuContext;
import master.flame.danmaku.danmaku.model.android.Danmakus;
import master.flame.danmaku.danmaku.parser.BaseDanmakuParser;
import master.flame.danmaku.danmaku.parser.IDataSource;
import master.flame.danmaku.ui.widget.DanmakuView;

/**
 * 包含弹幕的播放器
 * Created by liujingtao on 2019/2/25.
 */

public class DanmakuVideoView extends IjkVideoView implements DanmakuControllerInterfaceBase, View.OnClickListener {

    // 是否启用弹幕
    private boolean mDanmakuEnable;
    // 是否初始化显示弹幕
    private boolean mIsShowDanmakuInit;
//    private List<DanmakuDetail> mDanmakuDetails;
    // 弹幕视图
    private DanmakuView mDanmakuView;
    // 弹幕控制相关
    private DanmakuContext mDanmakuContext;
    // 弹幕解析器
    private BaseDanmakuParser mDanmakuParser;
    // 弹幕加载器
    private ILoader mDanmakuLoader;
    private TextView mTVWifiName;
    private View mBottomDivider;

    public DanmakuVideoView(@NonNull Context context) {
        this(context, null);
    }

    public DanmakuVideoView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public DanmakuVideoView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        initDanMuView();
    }

    @Override
    protected void initPlayer() {
        super.initPlayer();
        if (mDanmakuView != null) {
            mPlayerContainer.removeView(mDanmakuView);
            mPlayerContainer.addView(mDanmakuView, 1);
        }
    }


    @Override
    protected void startPrepare(boolean needReset) {
        super.startPrepare(needReset);

        if (mDanmakuView != null && mDanmakuParser != null && mDanmakuContext != null) {
            if (mVideoController instanceof DanmakuController) {
                showOrHideDanmaku(mIsShowDanmakuInit);
                mDanmakuView.prepare(mDanmakuParser, mDanmakuContext);
            } else {
                showOrHideDanmaku(false);
            }
        }

    }

    @Override
    protected void startInPlaybackState() {
        super.startInPlaybackState();
        if (mDanmakuView != null && mDanmakuView.isPrepared() && mDanmakuView.isPaused()) {
            mDanmakuView.resume();
        }
    }

    @Override
    public void pause() {
        super.pause();
        if (isInPlaybackState()) {
            if (mDanmakuView != null && mDanmakuView.isPrepared()) {
                mDanmakuView.pause();
            }
        }

//        if (isPlaying()) {
//            mMediaPlayer.pause();
//            setPlayState(STATE_PAUSED);
//            setKeepScreenOn(false);
////            if (mAudioFocusHelper != null)
////                mAudioFocusHelper.abandonFocus();
//        }

        if (mClingPlayControl != null) {
            /*mClingPlayControl.pause(new ControlCallback() {
                @Override
                public void success(IResponse response) {
                    Log.e(TAG, "pause success");
                }

                @Override
                public void fail(IResponse response) {
                    Log.e(TAG, "pause fail");
                }
            });*/

            if (mPopupWindow != null) {
                mPopupWindow.dismiss();
            }
        }
    }

    @Override
    public void resume() {
        super.resume();
        if (mDanmakuView != null && mDanmakuView.isPrepared() && mDanmakuView.isPaused()) {
            mDanmakuView.resume();
        }
    }

    @Override
    public void release() {
        super.release();
        if (mDanmakuView != null) {
            // dont forget release!
            mDanmakuView.release();
            mDanmakuView = null;
        }


        if (mDLNAEnable) {
            mHandler.removeCallbacksAndMessages(null);
            // Unbind UPnP service
            mContext.unbindService(mUpnpServiceConnection);
            mContext.unregisterReceiver(mTransportStateBroadcastReceiver);
            mBrowseRegistryListener.setOnDeviceListChangedListener(null);

            ClingManager.getInstance().destroy();
            ClingDeviceList.getInstance().destroy();
//        MemoryLeakUtil.fixLeak(this);
        }
        mContext = null;
        mHandler = null;
    }

    @Override
    public void seekTo(long pos) {
        // 片头片尾广告，不可设置进度
        if (PlayerConstants.VideoType.START_AD.equals(mCurrentVideoType)
                || PlayerConstants.VideoType.END_AD.equals(mCurrentVideoType)) {
            return;
        }
        super.seekTo(pos);
        if (isInPlaybackState()) {
            if (mDanmakuView != null) mDanmakuView.seekTo(pos);
        }
    }

    public void initDanMuView() {

        if (mVideoController instanceof DanmakuController) {
            ((DanmakuController) mVideoController).selectDanmakuControl(true);
        }

        // 设置最大显示行数
        HashMap<Integer, Integer> maxLinesPair = new HashMap<Integer, Integer>();
        maxLinesPair.put(BaseDanmaku.TYPE_SCROLL_RL, 5); // 滚动弹幕最大显示5行
        // 设置是否禁止重叠
        HashMap<Integer, Boolean> overlappingEnablePair = new HashMap<Integer, Boolean>();
        overlappingEnablePair.put(BaseDanmaku.TYPE_SCROLL_RL, true);
        overlappingEnablePair.put(BaseDanmaku.TYPE_FIX_TOP, true);

        mDanmakuView = new DanmakuView(getContext());
        mDanmakuContext = DanmakuContext.create();
        mDanmakuContext.setDanmakuStyle(IDisplayer.DANMAKU_STYLE_STROKEN, 3)
                .setDuplicateMergingEnabled(false)
//                .setScrollSpeedFactor(1.2f)
//                .setScaleTextSize(1.8f)
//                .setCacheStuffer(new BackgroundCacheStuffer(), mCacheStufferAdapter) // 图文混排使用SpannedCacheStuffer
//        .setCacheStuffer(new BackgroundCacheStuffer())  // 绘制背景使用BackgroundCacheStuffer
                .setMaximumLines(maxLinesPair)
                .preventOverlapping(overlappingEnablePair).setDanmakuMargin(40);
        if (mDanmakuView != null) {
//            mDanmakuParser = createParser(this.getResources().openRawResource(R.raw.commentstest));
            mDanmakuView.setCallback(new master.flame.danmaku.controller.DrawHandler.Callback() {
                @Override
                public void updateTimer(DanmakuTimer timer) {
                }

                @Override
                public void drawingFinished() {

                }

                @Override
                public void danmakuShown(BaseDanmaku danmaku) {
//                    Log.d("DFM", "danmakuShown(): text=" + danmaku.text);
                }

                @Override
                public void prepared() {
                    mDanmakuView.start();
//                    if (mDanmakuDetails != null && mDanmakuDetails.size() > 0) {
//                        for (DanmakuDetail floatingComment : mDanmakuDetails) {
//                            sendDanmu(1, floatingComment.getText(), 60f, -1, false);
//                        }
//                    }
                }
            });
            mDanmakuView.setOnDanmakuClickListener(new IDanmakuView.OnDanmakuClickListener() {

                @Override
                public boolean onDanmakuClick(IDanmakus danmakus) {
                    Log.d("DFM", "onDanmakuClick: danmakus size:" + danmakus.size());
                    BaseDanmaku latest = danmakus.last();
                    if (null != latest) {
                        Log.d("DFM", "onDanmakuClick: text of latest danmaku:" + latest.text);
                        return true;
                    }
                    return false;
                }

                @Override
                public boolean onDanmakuLongClick(IDanmakus danmakus) {
                    return false;
                }

                @Override
                public boolean onViewClick(IDanmakuView view) {
//                    mMediaController.setVisibility(View.VISIBLE);
                    return false;
                }
            });
//            mDanmakuView.prepare(mDanmakuParser, mDanmakuContext);
//            mDanmakuView.showFPS(true);
            mDanmakuView.enableDanmakuDrawingCache(true);
        }

    }

    public void enableDanmaku(DanmakuModel danmakuModel) {
        mDanmakuEnable = true;
        if (danmakuModel != null) {
//            mDanmakuDetails = danmakuModel.getDanmakuDetails();
            transFloatingComments(danmakuModel.getDanmakuDetails());
            if (danmakuModel.getScrollSpeed() > 0.0 && mDanmakuContext != null) {
                mDanmakuContext.setScrollSpeedFactor(danmakuModel.getScrollSpeed());
            }
        }

        mIsShowDanmakuInit = true; // 默认打开弹幕
//        if (mVideoController instanceof DanmakuController) {
//            ((DanmakuController) mVideoController).enableDanmaku();
//        }
    }

    public void enableDanmaku(DanmakuModel danmakuModel, String danmakuInitType) {
        mDanmakuEnable = true;
        if (danmakuModel != null) {
//            mDanmakuDetails = danmakuModel.getDanmakuDetails();
            transFloatingComments(danmakuModel.getDanmakuDetails());
            if (danmakuModel.getScrollSpeed() > 0.0 && mDanmakuContext != null) {
                mDanmakuContext.setScrollSpeedFactor(danmakuModel.getScrollSpeed());
            }
        }

        if (PlayerConstants.DanmakuInitType.OPEN.equals(danmakuInitType)) {
            mIsShowDanmakuInit = true;
        } else {
            mIsShowDanmakuInit = false;
        }

//        mIsShowDanmakuInit = showDanmakuInit;
//        if (mVideoController instanceof DanmakuController) {
//            ((DanmakuController) mVideoController).enableDanmaku();
//            if (mIsShowDanmakuInit) {
//                ((DanmakuController) mVideoController).showDanmakuInit();
//            }
//        }
    }

    private void transFloatingComments(List<DanmakuDetail> danmakuDetails) {
        if (danmakuDetails == null || danmakuDetails.size() < 1) {
            return;
        }
        String xmlNodes = parseNodeToXML(danmakuDetails);
        if (xmlNodes != null && xmlNodes.length() > 0) {
            mDanmakuParser = createParser(new ByteArrayInputStream(xmlNodes.getBytes()));
        } else {
            mDanmakuParser = createParser(null);
        }
    }

    private BaseDanmakuParser createParser(InputStream stream) {

        if (stream == null) {
            return new BaseDanmakuParser() {

                @Override
                protected Danmakus parse() {
                    return new Danmakus();
                }
            };
        }

        ILoader loader = DanmakuLoaderFactory.create(DanmakuLoaderFactory.TAG_BILI);

        try {
            loader.load(stream);
        } catch (IllegalDataException e) {
            e.printStackTrace();
        }
        BaseDanmakuParser parser = new BiliDanmukuParser();
        IDataSource<?> dataSource = loader.getDataSource();
        parser.load(dataSource);
        return parser;

    }

    /**
     * 发射弹幕
     *
     * @param text   内容
     * @param isLive 是否直播
     * @return 弹幕数据
     */
    @Override
    public void sendDanmu(int danmakuType, String text, float textSize, int textColor, boolean isLive) {
//        if (!mIsEnableDanmaku) {
//            throw new RuntimeException("Danmaku is disable, use enableDanmaku() first");
//        }
        if (TextUtils.isEmpty(text)) {
            Toast.makeText(getContext(), "内容为空", Toast.LENGTH_SHORT).show();
            return;
        }
        if (!mDanmakuView.isPrepared()) {
            Toast.makeText(getContext(), "弹幕还没准备好", Toast.LENGTH_SHORT).show();
            return;
        }
        BaseDanmaku danmaku = mDanmakuContext.mDanmakuFactory.createDanmaku(danmakuType);
        if (danmaku == null || mDanmakuView == null) {
            return;
        }

        danmaku.text = text;
        danmaku.padding = 5;
        danmaku.isLive = isLive;
        danmaku.priority = 0;  // 可能会被各种过滤器过滤并隐藏显示
        danmaku.textSize = textSize;
        danmaku.textColor = textColor;
        danmaku.underlineColor = Color.GREEN;
        danmaku.setTime(mDanmakuView.getCurrentTime() + 500);
        mDanmakuView.addDanmaku(danmaku);

//        if (mDanmakuListener != null) {
//            if (mDanmakuConverter != null) {
//                mDanmakuListener.onDataObtain(mDanmakuConverter.convertDanmaku(danmaku));
//            } else {
//                mDanmakuListener.onDataObtain(danmaku);
//            }
//        }
    }

    @Override
    public void showOrHideDanmaku(boolean isShow) {
        if (isShow) {
            mDanmakuView.show();
        } else {
            mDanmakuView.hide();
        }
    }

    @Override
    public void releaseDanmaku() {
        if (mDanmakuView != null) {
            mDanmakuView.release();
        }
    }

    public BaseDanmakuParser getDanmakuParser() {
        return mDanmakuParser;
    }


    /**
     * 连接设备状态: 播放状态
     */
    public static final int PLAY_ACTION = 0xa1;
    /**
     * 连接设备状态: 暂停状态
     */
    public static final int PAUSE_ACTION = 0xa2;
    /**
     * 连接设备状态: 停止状态
     */
    public static final int STOP_ACTION = 0xa3;
    /**
     * 连接设备状态: 转菊花状态
     */
    public static final int TRANSITIONING_ACTION = 0xa4;
    /**
     * 获取进度
     */
    public static final int GET_POSITION_INFO_ACTION = 0xa5; //todo  和ERROR_ACTION值重复了
    /**
     * 投放失败
     */
    public static final int ERROR_ACTION = 0xa5;

    private Context mContext;
    private Handler mHandler = new InnerHandler();

    private BroadcastReceiver mTransportStateBroadcastReceiver;

    private PopupWindow mPopupWindow;
    private LinearLayout mPopLayout;
    private ListView mDeviceList;
    private LinearLayout mLLSearching;
    private TextView mTVResearch;
    private ImageView mIvDLNAPopClose;

    private ArrayList<ClingDevice> mDevices = new ArrayList<>();
    private DLNADevicesAdapter mDevicesAdapter;

    private ClingDevice mSelectedDevice;

    private static ClingPlayControl mClingPlayControl = new ClingPlayControl();

    /**
     * 用于监听发现设备
     */
    private BrowseRegistryListener mBrowseRegistryListener = new BrowseRegistryListener();
    private ServiceConnection mUpnpServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            Log.e(TAG, "mUpnpServiceConnection onServiceConnected");

            ClingUpnpService.LocalBinder binder = (ClingUpnpService.LocalBinder) service;
            ClingUpnpService beyondUpnpService = binder.getService();

            ClingManager mClingUpnpServiceManager = ClingManager.getInstance();
            mClingUpnpServiceManager.setUpnpService(beyondUpnpService);
            mClingUpnpServiceManager.setDeviceManager(new DeviceManager());

            mClingUpnpServiceManager.getRegistry().addListener(mBrowseRegistryListener);
            mClingUpnpServiceManager.searchDevices();
        }

        @Override
        public void onServiceDisconnected(ComponentName className) {
            Log.e(TAG, "mUpnpServiceConnection onServiceDisconnected");
            ClingManager.getInstance().setUpnpService(null);
        }
    };
    private StandardVideoController mStandardVideoController;
    private boolean mDLNAEnable;


    public void enableDLNA() {
        mDLNAEnable = true;
        initDevicePopView();
        initListeners();
        bindServices();
        registerReceivers();
        notifyVideoControllerChange();
    }

    @Override
    protected void notifyVideoControllerChange() {

        if (mVideoController instanceof DanmakuController) {
            if (mDanmakuEnable) {
                ((DanmakuController) mVideoController).enableDanmaku();
                if (mIsShowDanmakuInit) {
                    ((DanmakuController) mVideoController).showDanmakuInit();
                }
            }
            if (mDLNAEnable) {
                ((DanmakuController) mVideoController).setControllerListener(new DLNAControllerInterface() {
                    @Override
                    public void onDLNAConnectClick() {
                        Log.d(TAG, "  onDLNAConnectClick()!!!!@@@@@@@@");
                        showDevicesPop();
                        ClingManager.getInstance().searchDevices();
                        mDeviceList.setEnabled(false);
                        refreshDeviceList();
                        mDeviceList.setEnabled(true);

                    }

                    @Override
                    public void onDLNAChangeDeviceClick() {
                        Log.d(TAG, "  onDLNAChangeDeviceClick()");
                        showDevicesPop();
                        ClingManager.getInstance().searchDevices();
                        mDeviceList.setEnabled(false);
                        refreshDeviceList();
                        mDeviceList.setEnabled(true);

                    }

                    @Override
                    public void onDLNAExitClick() {
                        Log.d(TAG, "  onDLNAExitClick()   !!!!@@@@@@@@");
                        ClingManager.getInstance().cleanSelectedDevice();
                        stopDLNA();
                        ((DanmakuController) mVideoController).setDLNADisableGesture(false);
                        hidePausedAd();
                        mMediaPlayer.start();
                        setPlayState(STATE_PLAYING);
                    }

                    @Override
                    public void onDLNADevicesClick() {

                    }

                    @Override
                    public void onDLNADefinitionClick() {

                    }

                    @Override
                    public void onDLNADismissPop() {
                        mPopupWindow.dismiss();
                    }
                });

                mStandardVideoController = getVideoController();
                mStandardVideoController.showDLNAIcon();
            }
        }


    }


    private void registerReceivers() {
        //Register play status broadcast
        mTransportStateBroadcastReceiver = new TransportStateBroadcastReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(Intents.ACTION_PLAYING);
        filter.addAction(Intents.ACTION_PAUSED_PLAYBACK);
        filter.addAction(Intents.ACTION_STOPPED);
        filter.addAction(Intents.ACTION_TRANSITIONING);
        mContext.registerReceiver(mTransportStateBroadcastReceiver, filter);
    }


    private void bindServices() {
        // Bind UPnP service
        Intent upnpServiceIntent = new Intent(mContext, ClingUpnpService.class);
        mContext.bindService(upnpServiceIntent, mUpnpServiceConnection, Context.BIND_AUTO_CREATE);
    }


    private void initDevicePopView() {
        mPopLayout = (LinearLayout) LayoutInflater.from((Activity) mContext).inflate(R.layout.layout_dlna_devices_pop, null);
        mPopupWindow = new PopupWindow(mPopLayout, (int) getResources().getDimension(R.dimen.dlna_pop_width), ViewGroup.LayoutParams.WRAP_CONTENT, true);
        mPopupWindow.setBackgroundDrawable(new ColorDrawable(0xaaffffff));
        mPopupWindow.setOutsideTouchable(true);
        mPopupWindow.setClippingEnabled(false);

        mDeviceList = mPopLayout.findViewById(R.id.dlna_lv_devices);
        mDeviceList.addHeaderView(new View(mContext));
//	    mDeviceList.addFooterView(new View(mContext));
        //mBottomDivider = mPopLayout.findViewById(R.id.dlna_bottom_divider);

        mDevicesAdapter = new DLNADevicesAdapter(mContext);
        mDeviceList.setAdapter(mDevicesAdapter);

        mIvDLNAPopClose = mPopLayout.findViewById(R.id.dlna_iv_pop_close);
        mTVWifiName = mPopLayout.findViewById(R.id.dlna_tv_wifi_name);
        mLLSearching = mPopLayout.findViewById(R.id.dlna_ll_search_devices_prompt);
        mTVResearch = mPopLayout.findViewById(R.id.dlna_tv_refresh_devices);

        mIvDLNAPopClose.setOnClickListener(this);
        mTVResearch.setOnClickListener(this);
    }

    private void initListeners() {
        mDeviceList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                stopDLNA();
                // 选择连接设备
//                mSelectedDevice = mDevicesAdapter.getItem(position);   //HeaderView也占位置
                mSelectedDevice = (ClingDevice) parent.getAdapter().getItem(position);
                if (Utils.isNull(mSelectedDevice)) {
                    return;
                }

                ClingManager.getInstance().setSelectedDevice(mSelectedDevice);
                Device device = mSelectedDevice.getDevice();
                if (Utils.isNull(device)) {
                    return;
                }


                Log.d(TAG, "***************** onItemClick name=" + device.getDetails().getFriendlyName());
                playDLNA();
                //mDevicesAdapter.setConnectedDevice(mSelectedDevice.getDevice());
            }
        });

        // 设置发现设备监听
        mBrowseRegistryListener.setOnDeviceListChangedListener(new DeviceListChangedListener() {
            @Override
            public void onDeviceAdded(final IDevice device) {
                ((Activity) mContext).runOnUiThread(new Runnable() {
                    public void run() {
                        mDevicesAdapter.add((ClingDevice) device);
                    }
                });
            }

            @Override
            public void onDeviceRemoved(final IDevice device) {
                ((Activity) mContext).runOnUiThread(new Runnable() {
                    public void run() {
                        mDevicesAdapter.remove((ClingDevice) device);
                    }
                });
            }
        });
    }

    private void refreshDeviceList() {
        Collection<ClingDevice> devices = ClingManager.getInstance().getDmrDevices();
        ClingDeviceList.getInstance().setClingDeviceList(devices);
        Log.d(TAG, "refreshDeviceList()   devices=" + devices);
        mDevicesAdapter.clear();
        if (devices != null) {
            ClingDeviceList.getInstance().setClingDeviceList(devices);
            mDevicesAdapter.addAll(devices);
        }

        //Android 8.0以后获取SSID为<unknown ssid>,使用后面一种方式解决
        /*WifiManager wifiMgr = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
        int wifiState = wifiMgr.getWifiState();
        WifiInfo info = wifiMgr.getConnectionInfo();
        String wifiId = info != null ? info.getSSID() : null;
        mTVWifiName.setText(wifiId.substring(1, wifiId.length()-1));*/

        ConnectivityManager ctm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo networkInfo = ctm.getActiveNetworkInfo();
        String ssid = networkInfo.getExtraInfo();
        if (ssid != null) {
            mTVWifiName.setText(ssid.substring(1, ssid.length() - 1));
        }

    }

    private void showDevicesPop() {
        Log.d(TAG, "showDevicesPop()");
        //下面measure操作会导致Android 8.0以上手机弹出框第二次显示时listitem不加载
        //mPopLayout.measure(View.MeasureSpec.AT_MOST, View.MeasureSpec.UNSPECIFIED);
        mPopupWindow.setWidth((int) getResources().getDimension(R.dimen.dlna_pop_width));
        mPopupWindow.showAtLocation(((Activity) mContext).getWindow().getDecorView(), Gravity.CENTER, 0, 0);
        Log.e(TAG, "showDevicesPop  getDimension=" + getResources().getDimension(R.dimen.dlna_pop_width)
                + "  mPopupWindow=" + mPopupWindow.getWidth());
    }

    private void stopDLNA() {
        mClingPlayControl.stop(new ControlCallback() {
            @Override
            public void success(IResponse response) {
                Log.e(TAG, "stop success");
            }

            @Override
            public void fail(IResponse response) {
                Log.e(TAG, "stop fail");
            }
        });
    }


    /**
     * 投屏播放视频
     */
    private void playDLNA() {
        @DLANPlayState.DLANPlayStates int currentState = mClingPlayControl.getCurrentState();

        /**
         * 通过判断状态 来决定 是继续播放 还是重新播放
         */
        if (currentState == DLANPlayState.STOP) {
            //todo  getVideoURL
            mClingPlayControl.playNew(mCurrentUrl, new ControlCallback() {

                @Override
                public void success(IResponse response) {
                    Log.e(TAG, "playNew success");
                    ((Activity) mContext).runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            mPopupWindow.dismiss();
                            if (isInPlaybackState()) {
                                if (mDanmakuView != null && mDanmakuView.isPrepared()) {
                                    mDanmakuView.pause();
                                }


                                Log.e(TAG, "playNew success  pause and show connected view");
//                                if (isPlaying()) {
                                mMediaPlayer.pause();
                                setPlayState(STATE_DLNA_CONNECTED);
                                ((DanmakuController) mVideoController).setDLNADisableGesture(true);
                                setKeepScreenOn(false);
//                                    if (mAudioFocusHelper != null)
//                                        mAudioFocusHelper.abandonFocus();
//                                }

                                mStandardVideoController.setConnectedDevice(mSelectedDevice);
                            }
                        }
                    });

                    ClingManager.getInstance().registerAVTransport(mContext);
                    ClingManager.getInstance().registerRenderingControl(mContext);
                }

                @Override
                public void fail(IResponse response) {
                    Log.e(TAG, "playNew fail");
                    mHandler.sendEmptyMessage(ERROR_ACTION);
                }
            });
        } else {
            mClingPlayControl.play(new ControlCallback() {
                @Override
                public void success(IResponse response) {
                    Log.e(TAG, "play success");
                    ((Activity) mContext).runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            mPopupWindow.dismiss();
                            if (isInPlaybackState()) {
                                if (mDanmakuView != null && mDanmakuView.isPrepared()) {
                                    mDanmakuView.pause();
                                }

                                Log.e(TAG, "play success  pause and show connected view");
//                                if (isPlaying()) {
                                mMediaPlayer.pause();
                                setPlayState(STATE_DLNA_CONNECTED);
                                ((DanmakuController) mVideoController).setDLNADisableGesture(true);
                                setKeepScreenOn(false);
//                                    if (mAudioFocusHelper != null)
//                                        mAudioFocusHelper.abandonFocus();
//                                }

                                mStandardVideoController.setConnectedDevice(mSelectedDevice);
                            }
                        }
                    });
                }

                @Override
                public void fail(IResponse response) {
                    Log.e(TAG, "play fail");
                    mHandler.sendEmptyMessage(ERROR_ACTION);
                }
            });
        }
    }


    @Override
    public void onClick(View v) {
        int i = v.getId();
        if (i == R.id.dlna_iv_pop_close) {
            mPopupWindow.dismiss();
        } else if (i == R.id.dlna_tv_refresh_devices) {
            mDevicesAdapter.clear();
            ClingManager.getInstance().searchDevices();
            mDeviceList.setEnabled(false);

            //todo  需要添加延时(刷新太快，看不到刷新过程)
            refreshDeviceList();
            mDeviceList.setEnabled(true);
        }
    }


    private final class InnerHandler extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case PLAY_ACTION:
                    Log.i(TAG, "Execute PLAY_ACTION");
                    //Toast.makeText(mContext, "正在投放", Toast.LENGTH_SHORT).show();
                    mClingPlayControl.setCurrentState(DLANPlayState.PLAY);
                    break;
                case PAUSE_ACTION:
                    Log.i(TAG, "Execute PAUSE_ACTION");
                    mClingPlayControl.setCurrentState(DLANPlayState.PAUSE);
                    break;
                case STOP_ACTION:
                    Log.i(TAG, "Execute STOP_ACTION");
                    mClingPlayControl.setCurrentState(DLANPlayState.STOP);
                    break;
                case TRANSITIONING_ACTION:
                    Log.i(TAG, "Execute TRANSITIONING_ACTION");
                    Toast.makeText(mContext, "正在连接", Toast.LENGTH_SHORT).show();
                    break;
                case ERROR_ACTION:
                    Log.e(TAG, "Execute ERROR_ACTION");
                    Toast.makeText(mContext, "投放失败", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
    }

    /**
     * 接收状态改变信息
     */
    private class TransportStateBroadcastReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.d(TAG, "\n\n*****************  Receive playback intent:" + action);
            if (Intents.ACTION_PLAYING.equals(action)) {
                mHandler.sendEmptyMessage(PLAY_ACTION);
            } else if (Intents.ACTION_PAUSED_PLAYBACK.equals(action)) {
                mHandler.sendEmptyMessage(PAUSE_ACTION);
            } else if (Intents.ACTION_STOPPED.equals(action)) {
                mHandler.sendEmptyMessage(STOP_ACTION);
            } else if (Intents.ACTION_TRANSITIONING.equals(action)) {
                mHandler.sendEmptyMessage(TRANSITIONING_ACTION);
            }
        }
    }

    public boolean isDanmakuEnable() {
        return mDanmakuEnable;
    }

    public void setDanmakuEnable(boolean mDanmakuEnable) {
        this.mDanmakuEnable = mDanmakuEnable;
    }

    public boolean isDLNAEnable() {
        return mDLNAEnable;
    }

//    public List<DanmakuDetail> getFloatingComments() {
//        return mDanmakuDetails;
//    }
//
//    public void setFloatingComments(List<DanmakuDetail> mDanmakuDetails) {
//        this.mDanmakuDetails = mDanmakuDetails;
//    }

    public String parseNodeToXML(List<DanmakuDetail> danmakuDetails) {
        StringBuffer xmlnodes = new StringBuffer();
        if (danmakuDetails != null && danmakuDetails.size() > 0) {
            xmlnodes.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
            xmlnodes.append("<i>");
            for (int i = 0; i < danmakuDetails.size(); i++) {
                DanmakuDetail danmakuDetail = danmakuDetails.get(i);
                int type = danmakuDetail.getType() > 0 ? danmakuDetail.getType() : 1;
                int fontSize = danmakuDetail.getFontSize() > 0 ? danmakuDetail.getFontSize() : 25;
                xmlnodes.append("<d p='" + danmakuDetail.getRelativeTime()
                        + "," + type + ", " + fontSize + ","
                        + danmakuDetail.getColor() + ",0,0,0,0"
                        + "'>" + danmakuDetail.getText() + "</d>");
            }
            xmlnodes.append("</i>");
        }

        return xmlnodes.toString();
    }
}
